home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume25 / QBATCH / part03 < prev    next >
Encoding:
Text File  |  1991-11-04  |  54.2 KB  |  1,470 lines

  1. Newsgroups: comp.sources.misc
  2. From: alan@tharr.UUCP (Alan Saunders)
  3. Subject:  v25i022:  QBATCH - a queued batch processing system for UNIX, Part03/06
  4. Message-ID: <1991Nov5.034753.5007@sparky.imd.sterling.com>
  5. X-Md4-Signature: 038344f1eff902afe3c6ae66e19fc871
  6. Date: Tue, 5 Nov 1991 03:47:53 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: alan@tharr.UUCP (Alan Saunders)
  10. Posting-number: Volume 25, Issue 22
  11. Archive-name: QBATCH/part03
  12. Environment: UNIX
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then unpack
  16. # it by saving it into a file and typing "sh file".  To overwrite existing
  17. # files, type "sh file -c".  You can also feed this as standard input via
  18. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  19. # will see the following message at the end:
  20. #        "End of archive 3 (of 6)."
  21. # Contents:  DESCRIPTION INSTALL doc/chap.02 doc/chap.07 doc/chap.08
  22. #   doc/chap.09 man/qbatch.l src/Makefile src/qc.c src/ql.c
  23. # Wrapped by root@vfib_d on Thu Oct 31 15:46:39 1991
  24. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  25. if test -f 'DESCRIPTION' -a "${1}" != "-c" ; then 
  26.   echo shar: Will not clobber existing file \"'DESCRIPTION'\"
  27. else
  28. echo shar: Extracting \"'DESCRIPTION'\" \(5580 characters\)
  29. sed "s/^X//" >'DESCRIPTION' <<'END_OF_FILE'
  30. X
  31. X     The QBATCH system and its related programs were
  32. X     written by Alan D. Saunders and are
  33. X     Copyright (c) Vita Services Ltd. 1990 and
  34. X     Copyright (c) Vita Fibres Ltd. 1991
  35. X     
  36. X     PLEASE read the NOTICE file for details.
  37. X
  38. QBATCH is a versatile queued batch processing system for *NIX.
  39. X
  40. XEach queue consists of a file containing information about the queue
  41. itself, and about all jobs currently present in the queue.  When the
  42. program 'qp' is run for a given queue, it will fork a child process for
  43. each job in the queue in turn, and wait for it to complete.  If there
  44. are no jobs present in the queue, qp will wait for a signal from one of
  45. the support programs, which will 'tell' it that another job has joined
  46. the queue, or that it should terminate.
  47. X
  48. XFeatures:
  49. X
  50. There can be as many queues as the system can support. Queues are
  51. named, and run asynchronously.  The processing of jobs running in one
  52. queue are totally independent of those in any other (subject of course
  53. to the independence of potentially shared resources such as data files
  54. and devices).
  55. X
  56. Queues can be started and stopped independently.  If a job is running
  57. in a queue which receives a stop signal from the 'qs' program (NOT
  58. SIGSTOP) qp will allow the job to run to completion before terminating
  59. unless the kill option is specified.
  60. X
  61. The priority (nice value) of all jobs running in a queue is defined
  62. when the queue is created, so prioritised queues can be configured.
  63. X
  64. Jobs running in a queue consist of shell scripts, created (or copied)
  65. by the js program.  The default shell is the bourne shell, but this can
  66. be overridden at submit time with the -s option to js.   The jobs run
  67. with the uid and gid of the submittor, and run in the environment
  68. ruling when the job was submitted.  All environment variables except
  69. those excluded deliberately are passed to the job, and the job will
  70. start in the submittors current working directory.  Fixed context
  71. queues may be configured which overrule the above, they may be
  72. configured to run under a specified default shell, with a specified
  73. uid and gid (NOT root), and with a pre-defined environment and working
  74. directory.  Access to fixed context queues may be restricted by user-
  75. name and group.
  76. X
  77. Stdout and stderr of running jobs is redirected to a 'monitor' This
  78. will normally be the queue monitor (specified or defaulted when the
  79. queue was created), but may be specified for individual jobs.  The
  80. pathspec of both the job file, and the monitor, may be accessed with
  81. the 'qf' program viz:  "tail -f `qf -m work`"  where 'work' is the name
  82. of a queue.
  83. X
  84. The status and contents of queues can be listed at any time using the
  85. X'ql' program.  Information can include the uid and gid under which jobs
  86. will run (are running), user name and tty of submittor,  date and time
  87. of submission, date and time current job started, and a meaningful job
  88. name or description.
  89. X
  90. If rc.QBATCH is configured in the system init script, all queues which
  91. were running when the system went down will be restarted. Any jobs
  92. present in the queues will also be restarted.
  93. X
  94. XFacilities:
  95. X
  96. inform user by mail, or tty message when job is complete.
  97. cancel jobs in queues, or kill running jobs.
  98. change the running order of jobs in queues.
  99. suspend and resume processing of jobs.
  100. start and stop the queue process engine at any time (even under cron or from
  101. X      another queue)
  102. disable submissions to a queue, and re-enable them.
  103. stop a queue, and wait until the current job has finished (useful for ensuring
  104. X      that the system is idle before a backup)
  105. list the status and contents of a queue.
  106. repeat (or kill and repeat) the currently running job in a queue.
  107. examine or edit the jcl of jobs in a queue, and examine the monitors.
  108. monitor (and perhaps account) the times taken by jobs in the queue.
  109. X
  110. Prevent deadlocks between batch programs accessing the same devices or data
  111. files by ensuring they are submitted to the same queue, then they can't run in
  112. parallel.
  113. X
  114. Prevent cpu hogging jobs from swamping the system by submitting them to
  115. low-priority queues.
  116. X
  117. Have a separate queue for humungous jobs that is started and stopped by cron
  118. out of working hours.
  119. X
  120. XEnsure all overnight work is running in queues, then a backup job can stop the
  121. queues, wait for current jobs to finish, and back up before restarting the
  122. queues.
  123. X
  124. Protect sensitive applications and data with file and directory permissions,
  125. then permit named users or groups to submit jobs to a fixed context queue.
  126. X
  127. Queues can only be created by root, so the system administrator can tune the
  128. configuration to provide optimum throughput.  It is frequently the case,
  129. particularly if a system is swapping heavily, or is short of swap space, that
  130. two jobs running one after the other in a queue, will process faster overall
  131. than if they were run concurrently.
  132. X
  133. Of course, porting and installing QBATCH isn't the end. Queue discipline has to
  134. be imposed in order for it to be of any benefit.  Scripts and commands
  135. triggering batch jobs will have to be changed to use QBATCH, and jobs normally
  136. run interactively which impose heavy system loads, will have to be
  137. reconfigured. (consider for example renaming 'make' as 'MAKE' and writing a
  138. X'make' script which submits 'MAKE' to a queue).  Of course there will always be
  139. the awkward user who decides to submit a large job into a high priority queue.
  140. Analysing the queue monitors should show this up, they contain a certain amount
  141. of profile timing for jobs run in the queue, and the uid and gid of the submittor.
  142. X
  143. This should give you a taste of what QBATCH has to offer.
  144. X
  145. Regards .. Alan
  146. X
  147. END_OF_FILE
  148. if test 5580 -ne `wc -c <'DESCRIPTION'`; then
  149.     echo shar: \"'DESCRIPTION'\" unpacked with wrong size!
  150. fi
  151. # end of 'DESCRIPTION'
  152. fi
  153. if test -f 'INSTALL' -a "${1}" != "-c" ; then 
  154.   echo shar: Will not clobber existing file \"'INSTALL'\"
  155. else
  156. echo shar: Extracting \"'INSTALL'\" \(4889 characters\)
  157. sed "s/^X//" >'INSTALL' <<'END_OF_FILE'
  158. X
  159. X    QBATCH Version 2.0 Installation notes and bewares
  160. X
  161. X    The QBATCH system and its related programs were
  162. X    written by Alan D. Saunders and are
  163. X    Copyright (c) Vita Services Ltd. 1990 and
  164. X    Copyright (c) Vita Fibres Ltd. 1991
  165. X
  166. X    PLEASE read the NOTICE file for details.
  167. X
  168. XFIRST READ ALL OF THE TEXT FILES IN THIS DIRECTORY!!! Then read those in the
  169. X'doc' directory. Then you will know what QBATCH is, and the conditions you
  170. are deemed to have accepted by compiling, installing, and using it.
  171. X
  172. XEspecially read the file doc/chap.09 (security). Some of the concepts outlined
  173. here may be overruled by it's contents.
  174. X
  175. Once you are satisfied, change directory to the src directory, and have
  176. a look at config.h.  You should find configuration options available
  177. which are supported by your system.  If not, there should be enough
  178. information contained therein to allow you to add further options if
  179. you both feel it necessary, and are capable.  Define the configuration
  180. for your platform by commenting out those options which are not
  181. supported, and uncommenting those (one in each group) which are.
  182. X
  183. Then look at the Makefile, and ensure that BINDIR is set to where you
  184. want the binaries installed, and that MANDIR is where you want the
  185. manual pages. Also check to see  if the defined paths for SPOOLPATH
  186. and QUEUEPATH are satisfactory for your system.  QUEUEPATH is where the
  187. actual queue files themselves go. The directory must exist. It must be
  188. world searchable, but should only be root writeable.  SPOOLPATH is
  189. where the batch files are created, again, the world should be able to
  190. look at the contents of these files (jcl and monitors), but only root
  191. should be able to create and delete them.
  192. X
  193. Now, if you are not your systems administrator, you are at his (or her)
  194. mercy.  Certain of the QBATCH programs need to be able to set user and
  195. group id's so they must be owned by root, and setuid. The Makefile
  196. assumes that the person running make, is actually root, and changes
  197. file modes accordingly.  Some of the programs simply will not work
  198. properly if they don't have the right modes and/or are not owned by
  199. root.
  200. X
  201. Try 'make' and see if there are any errors.  If you can resolve them,
  202. do so, BUT LET ME KNOW!!, I will include fixes, and or release patches
  203. as needed.
  204. X
  205. If you get a clean compilation, but are not logged in as root, remove
  206. the executables, and call your sysadmin to re-make as root.
  207. X
  208. Make the directories defined in QBATCH.h as SPOOLPATH and QUEUEPATH, and
  209. ensure they have the correct permissions.
  210. X
  211. If there are environment variables defined for users which are
  212. meaningless in a batch context (or harmful) create a file '.qxenv' in
  213. QUEUEPATH containing a list (one per line) of those environment
  214. variables to be EXCLUDED from batch jobs. Ensure it is readable
  215. X(only) by root.
  216. X
  217. If you are going to implement fixed context queues, create a file in
  218. QUEUEPATH called '.<queuename>rc' setting up the context and environment
  219. for the jobs, for each queue created using the -f option of qc.  (see
  220. the man page for qc).
  221. X
  222. Then make install, create some queues,  and try it out.
  223. X
  224. BEWAREs
  225. X
  226. QBATCH is only as good as the scripts it is running.  It has been
  227. running now for a year on several sparcstations and servers, and the
  228. only problems we have encountered have been on file permissions, where
  229. files have been created in the foreground in a setuid script(??), and
  230. the batch job has tried to delete those files
  231. X.... The batch job unless running in a fixed context queue with #QCONTEXT
  232. specified in the .<queuename>rc file, runs under the user's real uid!
  233. In these cases, the script hangs until someone types something on the
  234. system console.
  235. X
  236. Job control. I am aware that some systems do not support this (alright
  237. call me a liar!) Job control is only used in QBATCH, to group together
  238. any children which may be forked by a running job.  This is so that a
  239. signal (SIGSTOP, SIGCONT, and SIGKILL) sent to the pid of a running
  240. job, is actually propagated through it's children.  Unless you can find
  241. a way round this, if you need to do such a thing, you'll have to
  242. examine the 'ps' output to identify the children if any, and kill them
  243. by hand. (the job itself of course will receive the original signal).
  244. X
  245. truncate(), ftruncate(). Some systems don't support this either. It
  246. won't do any damage to QBATCH to leave it out, it's only there for
  247. tidiness' sake.  The queue files will grow as jobs are added, and
  248. shrink as they are processed or canceled.  Truncate is used to ensure
  249. that unused trailing space in a queue file is returned to the system.
  250. If you don't have it, and can't emulate it, You'll have to live with
  251. it.  If it becomes a problem, you'll have to periodically tidy up
  252. manually.
  253. X
  254. XEnjoy ... Alan Saunders August 30 1991
  255. X
  256. If you do come across any problems, with security or anything else
  257. relating to QBATCH, please contact me, as I hope you will if you design
  258. any enhancements or bug fixes.
  259. END_OF_FILE
  260. if test 4889 -ne `wc -c <'INSTALL'`; then
  261.     echo shar: \"'INSTALL'\" unpacked with wrong size!
  262. fi
  263. # end of 'INSTALL'
  264. fi
  265. if test -f 'doc/chap.02' -a "${1}" != "-c" ; then 
  266.   echo shar: Will not clobber existing file \"'doc/chap.02'\"
  267. else
  268. echo shar: Extracting \"'doc/chap.02'\" \(4776 characters\)
  269. sed "s/^X//" >'doc/chap.02' <<'END_OF_FILE'
  270. X             QBATCH .. a queued batch processing system for UNIX
  271. X
  272. X
  273. X         The QBATCH system and its related programs were
  274. X         written by Alan D. Saunders and are
  275. X         Copyright (c) Vita Services Ltd. 1990 and
  276. X         Copyright (c) Vita Fibres Ltd. 1991
  277. X
  278. X2. DESCRIPTION.
  279. X    
  280. X    A QBATCH queue is a file containing information relating to the queue
  281. X    itself, and to the jobs queued for processing therein.  The location of the
  282. X    queue is defined by the implementor, and compiled into the QBATCH programs.
  283. X    A queue is created using the qc program, which creates such a file in the
  284. X    defined location, and unless overridden by command line options, stores the
  285. X    default spooling path (where job files are created), monitor (where stdout
  286. X    and stderr are redirected), and nice value.  Any of these parameters may be
  287. X    overridden at queue creation time, or altered at any time, by using the
  288. X    same qc program (qv.).  The fixed context flag may also be set or altered
  289. X    in the same way.
  290. X
  291. X    The QBATCH queue process engine is the program qp.  For any active queue,
  292. X    qp runs in the background waiting for a signal from one of the support
  293. X    programs.  When such a signal is received, qp checks the contents of the
  294. X    queue and acts accordingly.  If a new job has been submitted to the queue
  295. X    (and one is not currently running), qp will fork a child process to handle
  296. X    it, then wait for the child to complete.  The child will setuid to the
  297. X    owner of the job, and setgid to the owners group. It will then attach
  298. X    stdout and stderr to the job's monitor, renice to the queue priority, and
  299. X    execute the job.  When the job has finished, qp is woken by a SIGCHLD. qp
  300. X    will then tidy up the queue, remove the job file, and if required, notify
  301. X    the job owner.
  302. X
  303. X    The action of qp in response to a signal is governed by a set of flags in
  304. X    the queue header.  These 'action' flags are:
  305. X
  306. X    repeat. If set, the currently running job will not be removed from the
  307. X        queue when it terminates or is killed, nor will it's job file be
  308. X        removed.  Instead, it will remain in the queue effectively as the
  309. X        next job to be processed.
  310. X
  311. X    kill.   If set, qp will send a SIGKILL to the currently running job, to
  312. X        terminate it immediately.
  313. X
  314. X    halt.   This flag is a toggle.  If it has changed from unset to set, qp
  315. X        will send a SIGHALT to the currently running job, to suspend it's
  316. X        processing.  If it has changed from set to unset, qp will send a
  317. X        SIGCONT to the job, to resume it's processing.  If it is unchanged,
  318. X        no action will be taken.
  319. X
  320. X    stop.   If set, when the current job (if any) terminates or is killed, qp
  321. X        itself will terminate.  If no job is running qp will terminate
  322. X        immediately.
  323. X
  324. X    If none of the above flags are set (or in the case of halt, toggled), then
  325. X    qp will check the count of jobs in the queue.  If further jobs are present,
  326. X    the next will be processed, otherwise qp will wait for another signal.
  327. X
  328. X    Programs which alter the settings of these flags are:
  329. X
  330. X    qs        (queue stop)     Sets the stop, and optionally the kill and or 
  331. X                repeat flags.
  332. X    jk        (job kill (remove))    May set the kill flag.
  333. X    jr      (job repeat)     Sets the repeat, and optionally the kill flag.
  334. X    qh        (queue halt)    Sets the halt flag if not already set.
  335. X    qg        (queue go)         Clears the halt flag if set.
  336. X
  337. X    There are two further flags stored in the queue header, both used by the js
  338. X    program:
  339. X
  340. X    fixed.  This indicates a fixed context queue.  This concept will be
  341. X        discussed later.
  342. X
  343. X    enabled.This flag determines whether the job submit program will submit jobs
  344. X        to the queue.  If unset, js will not submit jobs.
  345. X
  346. X    The enabled flag is set by qe, and unset by qd.
  347. X
  348. X    Jobs may be submitted to any permitted queue through the program js.  By
  349. X    default, any user can submit jobs to any queue.  Restriction of access is
  350. X    only available in fixed context queues (see later).  A queue which has it's
  351. X    enabled flag unset is disabled, and js will not submit a job to such a
  352. X    queue for any user.
  353. X
  354. X    Jobs may be removed from a queue by the job owner or by the super user
  355. X    using the jk program. If processing has already started, jk will refuse to
  356. X    remove the job unless the -k (kill running job) option is specified.
  357. X
  358. X    The position of jobs in a queue may be altered by the owner or super user
  359. X    with the jj program.  Controls prevent any user from jumping the queue by
  360. X    permitting only the super user to jump jobs to positions held by jobs owned
  361. X    by other users.
  362. X
  363. X    Listing the contents of a named queue is achieved with the ql program, and
  364. X    a list of queues available to a user is provided by qa.  Various
  365. X    information is provided by qf and qt.
  366. END_OF_FILE
  367. if test 4776 -ne `wc -c <'doc/chap.02'`; then
  368.     echo shar: \"'doc/chap.02'\" unpacked with wrong size!
  369. fi
  370. # end of 'doc/chap.02'
  371. fi
  372. if test -f 'doc/chap.07' -a "${1}" != "-c" ; then 
  373.   echo shar: Will not clobber existing file \"'doc/chap.07'\"
  374. else
  375. echo shar: Extracting \"'doc/chap.07'\" \(4825 characters\)
  376. sed "s/^X//" >'doc/chap.07' <<'END_OF_FILE'
  377. X
  378. X             QBATCH .. a queued batch processing system for UNIX
  379. X
  380. X
  381. X         The QBATCH system and its related programs were
  382. X         written by Alan D. Saunders and are
  383. X         Copyright (c) Vita Services Ltd. 1990 and
  384. X         Copyright (c) Vita Fibres Ltd. 1991
  385. X
  386. X7. TUNING.
  387. X
  388. X    What is tuning? I consider tuning, of a program, an application, or a
  389. X    system, to be an exercise consisting of modifying those parameters in the
  390. X    operation which may be modified, with the aim of optimising throughput.
  391. X
  392. X    How do you define optimum throughput?  My definition is:
  393. X    "optimum throughput is when both the load on system resources, and the
  394. X    complaints of users are at a minimum".
  395. X
  396. X    How do we achieve this?
  397. X
  398. X    a. By restraining large resource hungry jobs to a small number of low
  399. X       priority queues.  This frees up resources for other users, and other
  400. X       jobs, and reduces the complainers to those thus restricted.
  401. X
  402. X    b. By ensuring that users don't lose out by using the queued batch system
  403. X       instead of 'batch', or simply dumping the job into the background with
  404. X       '&'. This means providing a reasonable number of normal and high
  405. X       priority queues, and ensuring that the jobs go into the correct queues.
  406. X       This may mean creating submission scripts for some jobs, in other cases
  407. X       it may be just (?? &-)) a case of user training.
  408. X       If you have a situation where a large user base can be defined as a
  409. X       series of discrete 'teams' or workgroups, consider assigning queues on
  410. X       a workgroup basis.  Contention between users over job priority is
  411. X       easier to resolve under these conditions, and complaints will be fewer.
  412. X
  413. X    c. By monitoring the profile timings of jobs through each queue. The times
  414. X       taken  are reported in the monitor for each job processed.  They are
  415. X       also accumulated in the queue header.  A summary of timings may be
  416. X       displayed at any time with:
  417. X       qf -s <queuename>
  418. X       A typical display would be:
  419. X
  420. X
  421. X     Queue started     : Wed Oct  2 15:02:37 1991
  422. X
  423. X     Available for     : 5 Min 14.00 Sec
  424. X     No. Jobs Processed: 10
  425. X
  426. X    Times:            Actual            Av. Per Job
  427. X
  428. X    Queued             5:45.00 Sec               34.50 Sec
  429. X    Real             1:43.68 Sec               10.36 Sec
  430. X    User                0.60 Sec                0.06 Sec
  431. X    System                2.69 Sec                0.26 Sec
  432. X
  433. X    Utilisation (real/available) 33.01%
  434. X
  435. X    Current job not accounted for above, running for : 7.00 Sec
  436. X
  437. X    (not actually typical, this is from my development system, not a live
  438. X    system).
  439. X
  440. X    The figures are:
  441. X    Queued:    The time a job was on the queue before starting to process.
  442. X    Real:    The actual (wall clock) time from start to end of processing.
  443. X    User:    The user cpu time taken by the job.
  444. X    System:    The system cpu time taken by the job.
  445. X
  446. X    Ideally, if a system is correctly tuned, the average timings of a given
  447. X    queue should only vary within limits.  Any wider variance is a reason to
  448. X    look at the individual times in the monitors.
  449. X
  450. X    Consistently low utilisation would probably indicate that jobs
  451. X    submitted to this queue could probably share resources better by being
  452. X    submitted to another low utilisation queue, and removing this one.
  453. X    Conversely, consistently high utilisation could mean that too many jobs
  454. X    are being submitted to this queue, and the load might be better split.
  455. X
  456. X    As discussed in the chapter on configuration, queues should be configured
  457. X    initially on the basis of resource requirement.  Jobs requiring the same
  458. X    (potentially limited) resources should be submitted to the same queue, so
  459. X    that there are no additional scheduling overheads imposed on the kernel for
  460. X    these jobs.  This may well be a case of trial and error, it may not be
  461. X    possible to predict what resources are demanded by a test job submitted by
  462. X    a programmer on a new project.  This really indicates that QBATCH use, once
  463. X    implemented in a system, should be designed into new systems by the
  464. X    programmers themselves, who would then (hopefully), design the programs,
  465. X    and supporting scripts with system policy, and resource availability in
  466. X    mind.
  467. X
  468. X    In short, there is no short answer to tuning.  QBATCH can provide the tools
  469. X    for better utilisation of resources, but to be effective, It needs to be
  470. X    implemented throughout a system, with no back doors through which users can
  471. X    'steal' resources.  It will take monitoring over a period of time, closing
  472. X    loopholes, and warning users who do not comply.  It will take creation of
  473. X    new queues at different priorities to share the workload equitably. It will
  474. X    take swapping jobs from queue to queue until the balance is right.  It will
  475. X    take WORK! (I know .. it's a dirty word.) You will know when you have got
  476. X    it right when the 'phone stops ringing.
  477. END_OF_FILE
  478. if test 4825 -ne `wc -c <'doc/chap.07'`; then
  479.     echo shar: \"'doc/chap.07'\" unpacked with wrong size!
  480. fi
  481. # end of 'doc/chap.07'
  482. fi
  483. if test -f 'doc/chap.08' -a "${1}" != "-c" ; then 
  484.   echo shar: Will not clobber existing file \"'doc/chap.08'\"
  485. else
  486. echo shar: Extracting \"'doc/chap.08'\" \(4681 characters\)
  487. sed "s/^X//" >'doc/chap.08' <<'END_OF_FILE'
  488. X
  489. X             QBATCH  a queued batch processing system for UNIX
  490. X
  491. X
  492. X         The QBATCH system and its related programs were
  493. X         written by Alan D. Saunders and are
  494. X         Copyright (c) Vita Services Ltd. 1990 and
  495. X         Copyright (c) Vita Fibres Ltd. 1991
  496. X
  497. X8.FIXED context queues.
  498. X
  499. X       A fixed context queue is one where the 'environment' of a job running
  500. X       in it is fixed.  A control file, located in the same directory as the
  501. X       queue itself, contains directives, and perhaps initial jcl which will
  502. X       set up and fix the running environment of all jobs processed in the
  503. X       queue.  This control file (.<queuename>rc in QUEUEPATH) may also be
  504. X       used to restrict access to the queue.
  505. X
  506. X       Fixed context queues were designed for those occasions when a job must
  507. X       run, but where the environment, (PATH, CWD etc) is unpredictable,
  508. X       non-existent, or must be fixed for a particular application.  The
  509. X       original tasks for which I designed this concept were jobs run
  510. X       remotely via uux.  Others which spring to mind are, complex
  511. X       mailservers, and user add-ons to an externally supplied application.
  512. X
  513. X       In it's simplest form, a job running in a fixed context queue does not
  514. X       carry the environment variables present when the job was submitted,
  515. X       but only those set up in the control file for that queue.  The control
  516. X       file may also contain jcl (such as changing directories, mounting
  517. X       secure partitions) which will be run before the submitted jcl. It can
  518. X       also be used to specify the shell under which the job will run instead
  519. X       of /bin/sh.
  520. X
  521. X       The shell can be specified by including a line
  522. X
  523. X       #!<shellpathspec>
  524. X
  525. X       as the FIRST line in the control file.  This will overrule ANY other
  526. X       specification of the shell to run under. (even the -s option to js will
  527. X       be silently ignored).  The reason for this is that any 'jcl' in the
  528. X       control file, even that setting environment variables, is shell
  529. X       specific.  Syntax suitable for the bourne shell is not suitable for the
  530. X       c-shell etc.
  531. X
  532. X       Extensions to this simple case are created by the use of #Q directives
  533. X       in the control file.
  534. X
  535. X       Using them you can:
  536. X       Have all jobs in this queue run under a particular uid and gid,
  537. X       (#QCONTEXT)
  538. X       NOTE A fixed context queue with a #QCONTEXT directive instructing the
  539. X       jobs to run as root IS NOT PERMITTED!
  540. X
  541. X       Limit access to this queue to a given list of users
  542. X       (#QUSERS)
  543. X
  544. X       limit access to this queue to a given list of groups
  545. X       (#QGROUPS)
  546. X
  547. X       Include selected environment variables into the environment of the job.
  548. X       (#QGETENV)
  549. X
  550. X       These facilities are available ONLY if the appropriate #Q directives
  551. X       are present.  Adequate security of the .<queuename>rc file will
  552. X       prevent malicious inclusion of say #QCONTEXT directives.
  553. X
  554. X       For details of the use and syntax of #Q directives, see the man page
  555. X       for qc (queue create).
  556. X
  557. X       Additionally, environment variables may be set for the job using 
  558. X       #ENV directives.  These are normally generated by js, either for all the
  559. X       environment in a normal queue, or for environment variables directed by
  560. X       #QGETENV directives in a fixed context queue.  The syntax is:
  561. X
  562. X       #ENV <environment variable>=<value>
  563. X
  564. X       e.g.
  565. X       #ENV PATH=/usr/ucb:/usr/bin
  566. X
  567. X       There should be one or more spaces or tabs after #ENV, and NOWHERE ELSE
  568. X       (except in a quoted string).
  569. X
  570. X       The #ENV directive is read by qp (the queue process engine) to set up
  571. X       an environment table for the job independent of the shell under which
  572. X       it will run.
  573. X
  574. X       The #Q directives are read by js, both to handle queue restrictions,
  575. X       and generate #ENV directives.
  576. X
  577. X       The control file may also contain any 'jcl' or script code valid in the
  578. X       shell under which the job is to run.
  579. X
  580. X       It is possible, using fixed context queues to effectively turn almost
  581. X       any program into a pseudo daemon.  qp reads the jcl file submitted, and
  582. X       creates an argument list based on the first line.  It then adds the jcl
  583. X       filespec as the last argument.  It then reads through the jcl file,
  584. X       setting up an environment table according to #ENV directives contained
  585. X       in it.  It then exec's the appropriate shell with the generated
  586. X       argument and environment tables.
  587. X
  588. X       The 'shell' specified does not have to be a bona fide shell.  It can be
  589. X       any program which can handle the syntax of the script submitted to it.
  590. X       The only proviso is that it must ignore any lines beginning with '#'.
  591. END_OF_FILE
  592. if test 4681 -ne `wc -c <'doc/chap.08'`; then
  593.     echo shar: \"'doc/chap.08'\" unpacked with wrong size!
  594. fi
  595. # end of 'doc/chap.08'
  596. fi
  597. if test -f 'doc/chap.09' -a "${1}" != "-c" ; then 
  598.   echo shar: Will not clobber existing file \"'doc/chap.09'\"
  599. else
  600. echo shar: Extracting \"'doc/chap.09'\" \(4524 characters\)
  601. sed "s/^X//" >'doc/chap.09' <<'END_OF_FILE'
  602. X
  603. X                QBATCH 
  604. X
  605. X    The QBATCH system and its related programs were
  606. X    written by Alan D. Saunders and are
  607. X    Copyright (c) Vita Services Ltd. 1990 and
  608. X    Copyright (c) Vita Fibres Ltd. 1991
  609. X
  610. X    Because of the nature of QBATCH, some of the programs have to run setuid
  611. X    as root.  THIS IS A POTENTIAL SECURITY HOLE!! Unless you ensure that only
  612. X    root can copy or write to them. Setuid programs are dangerous unless
  613. X    properly protected.  On systems (like SunOS) where linking is by default
  614. X    dynamic (using shared libraries), it is highly recommended that the ld
  615. X    switch forcing static linking be used for setuid programs (-Bstatic).
  616. X    This aside, I am not aware of any security problems caused by QBATCH.
  617. X    Systems administrators who are uncomfortable with the concept of fixed
  618. X    context queues can satisfy themselves that if the programs and support
  619. X    files are properly protected, they can enhance rather than degrade
  620. X    security.  NOTE a fixed context queue running as root is not permitted.
  621. X    If they are still not satisfied, they can always disable the option by
  622. X    removing the 'f' from the getopts statement in qc.c.  The code is there
  623. X    to be vetted if you are worried, there's nothing hidden, and I've nothing
  624. X    to hide; satisfy yourself.
  625. X
  626. X    Considerations:  qp needs to be running in root context since it actually
  627. X    has to setuid itself to the appropriate uid and gid when a job is
  628. X    forked.
  629. X
  630. X    qf, ql, and qw need read access ONLY to the queue files.
  631. X
  632. X    jj, jm, jn, jr, qc, qd, qe, qh, qg, and qs need read and write access
  633. X    ONLY to the queue files.
  634. X
  635. X    js and jk need read and write access to both the queue files, and the jcl
  636. X    files created.
  637. X
  638. X    The user submitting the job (the job owner except in the case of a fixed
  639. X    context queue) needs read access to the monitor files created, and may
  640. X    need read, (and possibly write) access to the jcl files created.
  641. X
  642. X    In the current implementation (I AM AWARE THAT THIS IS NOT IDEAL.. Any
  643. X    ideas?), the queue files themselves are owned by root, with owner read
  644. X    and write access, and world readable. All programs are owned by root.
  645. X
  646. X    A. qf, qw, and ql are not setuid, and are owner only read and write, but
  647. X    world executable.
  648. X
  649. X    B. qc, qe, qd, qh, qg, qp, and qs are not setuid, and are owner only
  650. X    read, write and execute. There is no world access, and they further check
  651. X    that the user is root when they are run.
  652. X
  653. X    C. jj, jk, jm, jn, jr, and js are setuid, are owner read and write, and
  654. X    world executable.
  655. X
  656. X    If a user (with a locked password) were created (say QBATCH), and all
  657. X    queue files and programs were owned by this user, then:
  658. X
  659. X    Group A would be unchanged.
  660. X
  661. X    Group B would be unchanged except for qc, which would have to change the
  662. X    ownership of the newly created queue.
  663. X
  664. X    Group C would be unchanged except:
  665. X
  666. X    js would STILL need to be setuid root since it needs both to write to the
  667. X    queue file, and to create the jcl and change it's ownership.
  668. X
  669. X    jk also would need to be setuid root since it needs both to write to the
  670. X    queue file, and delete the jcl file.
  671. X
  672. X    I am sure that the security from a system viewpoint could be improved.  I
  673. X    AM OPEN TO SUGGESTIONS!!
  674. X
  675. X    The files that really need to be secure are:
  676. X
  677. X    The queues themselves       (lest someone patch the uid field)
  678. X    The jcl files               (should only be readable/writeable by the job
  679. X                    owner)
  680. X    The .<qname>rc files    (should only be readable by js)
  681. X    The .qxenv file                     (ditto)
  682. X
  683. X    I do not feel that the monitor files are a security risk, Any user needs
  684. X    to be able to check the success or otherwise of jobs submitted by him.
  685. X    If jobs are to be run where sensitive information is sent to stdout or
  686. X    stderr, then the separate monitor (-m) option of js can be used.
  687. X
  688. X    CAN YOU SEE ANY OTHER HOLES?
  689. X
  690. X    Whilst I am aware of potential shortcomings in the current
  691. X    implementation, I do not intend making any changes until I have had
  692. X    sufficient feedback from the 'net.  If you can see better ways than I
  693. X    have outlined, for retaining the functionality whilst improving the
  694. X    security, I will be more than pleased to hear from you.  The next release
  695. X    of QBATCH will certainly contain improvements in this area.  If you want
  696. X    to use QBATCH, and are security concious, but don't want to wait for the
  697. X    next release, feel free to make changes as you deem fit, either those
  698. X    outlined above, or your own (BUT please let me know what you have done).
  699. END_OF_FILE
  700. if test 4524 -ne `wc -c <'doc/chap.09'`; then
  701.     echo shar: \"'doc/chap.09'\" unpacked with wrong size!
  702. fi
  703. # end of 'doc/chap.09'
  704. fi
  705. if test -f 'man/qbatch.l' -a "${1}" != "-c" ; then 
  706.   echo shar: Will not clobber existing file \"'man/qbatch.l'\"
  707. else
  708. echo shar: Extracting \"'man/qbatch.l'\" \(5230 characters\)
  709. sed "s/^X//" >'man/qbatch.l' <<'END_OF_FILE'
  710. X.TH QBATCH 5L "11 May 1991" QBATCH "QUEUED BATCH PROCESSING SYSTEM"
  711. X.SH COPYRIGHT
  712. The
  713. X.B QBATCH
  714. system and its related programs are:
  715. X.br
  716. Copyright (c) Vita Services Ltd. 1990
  717. X.br
  718. Copyright (c) Vita Fibres Ltd. 1991
  719. X.SH NAME 
  720. X.TP 12
  721. X.B QBATCH
  722. A queued batch processing system for UNIX
  723. X.TP
  724. X.B qa
  725. Queue availability. List the queues the user can submit jobs to.
  726. X.TP
  727. X.B qc
  728. Queue create. create a batch processing queue with an optional 
  729. processing priority, and spooling area            
  730. X.TP
  731. X.B qp
  732. Queue process. start a process engine for a given queue
  733. X.TP
  734. X.B qh
  735. Queue halt. suspend processing of current job in this queue.
  736. X.TP
  737. X.B qg
  738. Queue go. resume processing of current job in this queue.
  739. X.TP
  740. X.B qd
  741. Queue disable. Prevent jobs being submitted to this queue.
  742. X.TP
  743. X.B qe
  744. Queue enable. Enable jobs to be submitted to this queue.
  745. X.TP
  746. X.B qs
  747. Queue stop. Set the stop flag for a given queue so that qp
  748. terminates when current job is finished.           
  749. X(optionally to kill or repeat and kill current job)
  750. X.TP
  751. X.B qt
  752. Queue test. test various aspects of the queue status.
  753. X.TP
  754. X.B qw
  755. Queue wait. Wait until the queue process engine has terminated.
  756. X.TP
  757. X.B qf
  758. Queue find information. Reports (on stdout) requested information
  759. about the queue.
  760. X.TP
  761. X.B js
  762. Job submit. submit a job to an existing queue.
  763. X.TP
  764. X.B jj
  765. Job jump. move an entry towards the front of the queue.
  766. X.TP
  767. X.B jk
  768. Job kill. remove a job from this queue (optionally kill it).
  769. X.TP
  770. X.B jr
  771. Job repeat. repeat (optionally to kill) current job.
  772. X.TP
  773. X.B jm
  774. Job monitor. Add or alter monitor for a given job.
  775. X.TP
  776. X.B jn
  777. Job name. Add or alter name for a given job
  778. X.TP
  779. X.B rc.QBATCH
  780. Script (called from system boot script) to restart queues after a reboot.
  781. X.TP
  782. X.B jobdone
  783. This is the interface script between qp (the queue
  784. process engine) And the submitting user. 
  785. On completion of a job in a queue, this script is
  786. called to notify the user.
  787. X
  788. X.SH SYNOPSIS
  789. Command synopses are provided in separate man pages for each of the above commands.
  790. X
  791. X.SH DESCRIPTION:
  792. X
  793. QBATCH was written to overcome the limitations of the UNIX at and batch 
  794. commands where there is a need for potentially several job queues containing
  795. jobs to be processed in a specific order. On some versions of UNIX, it is 
  796. possible to gain this effect by utilising the print spooling system. QBATCH
  797. provides a portable, consistent method of achieving this object on all 
  798. flavours of UNIX.
  799. X
  800. The central 'tool' of QBATCH is the queue. The queue is a file, created
  801. in a known position in the filesystem, which contains information and
  802. flags used by the process subsystem, and entries relating to each job
  803. in the queue. There may be several such queue files, each pertaining
  804. perhaps to a different application or 'job stream'. Each queue is handled
  805. and processed separately, and may each be running it's jobs at a different
  806. priority (or 'nice' value). This allows background jobs to be scheduled at
  807. priorities relating to their importance, and their potential system load.
  808. X
  809. A job which is submitted to a queue is processed by the queue process engine,
  810. an activity running in the background for each queue. The jcl comprising the 
  811. job itself is in the form of a script file in the appropriate spooling directory.
  812. This file contains additional jcl created by the js program which initiates
  813. the users jobs with the same environment, and in the same working directory
  814. as was applicable at the time the job was submitted. The exception to this is
  815. the 'fixed context queue'. A queue (which must be created by 'root') may have
  816. a flag set which causes the jobs running in it to ignore the submitting user's 
  817. environment and context, and instead take it from a steering file. Access to these queues
  818. is controlled by the contents of the steering file.
  819. X.sp
  820. Three additional 
  821. environment variables are created by the process engine. These are:
  822. X
  823. X.nf
  824. QBC    A count of the number of times this job has been repeated.
  825. QUEUE   The name of the queue in which this job is running.
  826. QENTRY    The entry number of the job in the queue.
  827. X.fi
  828. X
  829. Note: Because of potential problems with some environment variables when
  830. running in a batch context, a mechanism is provided for excluding portions
  831. of the environment from this process.  If a file '.qxenv' is present in the
  832. QUEUEPATH directory, it is interpreted as a list (one per line) of environment
  833. variables to be EXCLUDED from the job.
  834. X
  835. Output from jobs running in queues (stdin and stderr) are redirected to a
  836. monitor file. This will either be the default monitor for the queue,
  837. specified or defaulted when the queue was created, or one specified for a 
  838. given job.
  839. X
  840. Script files containing the running jcl for jobs submitted to a queue are
  841. created in a spooling directory specified or defaulted when the queue was 
  842. created.
  843. X.SH NOTE
  844. All
  845. X.B QBATCH
  846. programs, even when not specifically documented will return the current
  847. X.B QBATCH
  848. version number, patch level and release date if run with the -v option.
  849. X.SH FILES
  850. X.ft B
  851. QUEUEPATH/*
  852. X.SH "SEE ALSO"
  853. X.BR jj (1L)
  854. X.BR jk (1L)
  855. X.BR jm (1L)
  856. X.BR jn (1L)
  857. X.BR jr (1L)
  858. X.BR js (1L)
  859. X.BR qa (1L)
  860. X.BR qc (1L)
  861. X.BR qd (1L)
  862. X.BR qe (1L)
  863. X.BR qf (1L)
  864. X.BR qg (1L)
  865. X.BR qh (1L)
  866. X.BR ql (1L)
  867. X.BR qp (1L)
  868. X.BR qt (1L)
  869. X.BR qs (1L)
  870. X.BR qw (1L)
  871. X.BR rc.QBATCH (8L)
  872. X.BR jobdone (8L)
  873. X.BR queue (5L)
  874. X.BR qxenv (5L)
  875. END_OF_FILE
  876. if test 5230 -ne `wc -c <'man/qbatch.l'`; then
  877.     echo shar: \"'man/qbatch.l'\" unpacked with wrong size!
  878. fi
  879. # end of 'man/qbatch.l'
  880. fi
  881. if test -f 'src/Makefile' -a "${1}" != "-c" ; then 
  882.   echo shar: Will not clobber existing file \"'src/Makefile'\"
  883. else
  884. echo shar: Extracting \"'src/Makefile'\" \(4658 characters\)
  885. sed "s/^X//" >'src/Makefile' <<'END_OF_FILE'
  886. X#    Makefile for QBATCH
  887. X#
  888. X# Targets are :
  889. X# all:        Compile all programs and generate scripts
  890. X# install:    Copy programs and scripts into $(BINDIR)
  891. X# inst_man:    Copy nroff source man pages into $(MANDIR)
  892. X# make_doc:    Nroff man pages into readable documents (in ../doc)
  893. X# clean:    Remove core files, object files and programs from src.
  894. X#        WARNING do NOT make clean before make install!
  895. X# shar:        Repackage QBATCH as a shar kit.
  896. CFLAG=-g
  897. LDFLAG=-Bstatic
  898. X
  899. X# the directory into which to move the binaries
  900. BINDIR=/usr/local/bin
  901. X
  902. X# the directory into which to install the man pages
  903. MANDIR=/usr/man/manl
  904. X
  905. X# the bourne shell path
  906. SHELL=/bin/sh
  907. X
  908. X# configuration of working paths
  909. X# N.B. Include the quotes and the trailing '/' in the defined string
  910. X# both should be absolute paths (i.e leading '/'
  911. X
  912. X# first, where the queues themselves reside
  913. QUEUEPATH="/qbatch/"
  914. X
  915. X# where QBATCH creates it's job files and default monitors
  916. SPOOLPATH="/var/spool/batch/"
  917. X
  918. QPATHS=-DQUEUEPATH=\"$(QUEUEPATH)\" -DSPOOLPATH=\"$(SPOOLPATH)\"
  919. PROGS=jj jk jm jn jr js qa qc qd qe qf qg qh ql qp qs qt qw rc.QBATCH jobdone
  920. X
  921. all:    $(PROGS)
  922. X    @echo "\n\007programs and scripts ... make complete\n"
  923. X
  924. jj:    jj.c qbatch.h  config.o
  925. X    cc $(CFLAG) $(LDFLAG) $(QPATHS) $@.c config.o  -o $@
  926. X    chmod 06711 $@
  927. X
  928. jk:    jk.c qbatch.h  config.o
  929. X    cc $(CFLAG) $(LDFLAG) $(QPATHS) $@.c config.o  -o $@
  930. X    chmod 06711 $@
  931. X
  932. jm:    jm.c qbatch.h  config.o
  933. X    cc $(CFLAG) $(LDFLAG) $(QPATHS) $@.c config.o  -o $@
  934. X    chmod 06711 $@
  935. X
  936. jn:    jn.c qbatch.h  config.o
  937. X    cc $(CFLAG) $(LDFLAG) $(QPATHS) $@.c config.o  -o $@
  938. X    chmod 06711 $@
  939. X
  940. jr:    jr.c qbatch.h  config.o
  941. X    cc $(CFLAG) $(LDFLAG) $(QPATHS) $@.c config.o  -o $@
  942. X    chmod 06711 $@
  943. X
  944. js:    js.c qbatch.h  config.o
  945. X    cc $(CFLAG) $(LDFLAG) $(QPATHS) $@.c config.o  -o $@
  946. X    chmod 06711 $@
  947. X
  948. qa:    qagen Makefile
  949. X    $(SHELL) qagen $(SHELL) $(BINDIR) $(QUEUEPATH)
  950. X    chmod 0755 $@
  951. X
  952. qc:    qc.c qbatch.h config.o
  953. X    cc $(CFLAG) $(LDFLAG) $(QPATHS) $@.c config.o  -o $@
  954. X    chmod 0700 $@
  955. X
  956. qd:    qd.c qbatch.h  config.o
  957. X    cc $(CFLAG) $(LDFLAG) $(QPATHS) $@.c config.o  -o $@
  958. X    chmod 0700 $@
  959. X
  960. qe:    qe.c qbatch.h  config.o
  961. X    cc $(CFLAG) $(LDFLAG) $(QPATHS) $@.c config.o  -o $@
  962. X    chmod 0700 $@
  963. X
  964. qf:    qf.c qbatch.h
  965. X    cc $(CFLAG) $(LDFLAG) $(QPATHS) $@.c  -o $@
  966. X    chmod 0711 $@
  967. X
  968. qg:    qg.c qbatch.h  config.o
  969. X    cc $(CFLAG) $(LDFLAG) $(QPATHS) $@.c config.o  -o $@
  970. X    chmod 0700 $@
  971. X
  972. qh:    qh.c qbatch.h  config.o
  973. X    cc $(CFLAG) $(LDFLAG) $(QPATHS) $@.c config.o  -o $@
  974. X    chmod 0700 $@
  975. X
  976. ql:    ql.c qbatch.h
  977. X    cc $(CFLAG) $(LDFLAG) $(QPATHS) $@.c -o $@
  978. X    chmod 0711 $@
  979. X
  980. qp:    qp.c qbatch.h  config.o time.o
  981. X    cc $(CFLAG) $(LDFLAG) $(QPATHS) $@.c config.o time.o  -o $@
  982. X    chmod 0700 $@
  983. X
  984. qs:    qs.c qbatch.h  config.o
  985. X    cc $(CFLAG) $(LDFLAG) $(QPATHS) $@.c config.o  -o $@
  986. X    chmod 0700 $@
  987. X
  988. qt:    qt.c qbatch.h
  989. X    cc $(CFLAG) $(LDFLAG) $(QPATHS) $@.c -o $@
  990. X    chmod 06711 $@
  991. X
  992. qw:    qw.c qbatch.h  config.o
  993. X    cc $(CFLAG) $(LDFLAG) $(QPATHS) $@.c config.o  -o $@
  994. X    chmod 0711 $@
  995. X
  996. jobdone:    jdgen Makefile
  997. X        $(SHELL) jdgen $(SHELL) $(BINDIR) $(QUEUEPATH)
  998. X        chmod 0711 jobdone
  999. X
  1000. rc.QBATCH:    rcgen Makefile
  1001. X        $(SHELL) rcgen $(SHELL) $(BINDIR) $(QUEUEPATH)
  1002. X        chmod 0700 rc.QBATCH
  1003. X
  1004. config.o:    config.c config.h qbatch.h
  1005. X        cc $(CFLAG) $(QPATHS) -c config.c
  1006. X
  1007. time.o:        config.h 
  1008. X        cc $(CFLAG) $(QPATHS) -c time.c
  1009. X
  1010. qbatch.h:    what.h Makefile
  1011. X        touch qbatch.h
  1012. X
  1013. what.h:    patchlevel.h
  1014. X    $(SHELL) < ./whatgen
  1015. X    
  1016. install:    $(BINDIR)/jj $(BINDIR)/jk $(BINDIR)/jm $(BINDIR)/jn \
  1017. X        $(BINDIR)/jr $(BINDIR)/js $(BINDIR)/qa $(BINDIR)/qc \
  1018. X        $(BINDIR)/qd $(BINDIR)/qe $(BINDIR)/qf $(BINDIR)/qg \
  1019. X        $(BINDIR)/qh $(BINDIR)/ql $(BINDIR)/qp $(BINDIR)/qs \
  1020. X        $(BINDIR)/qw $(BINDIR)/rc.QBATCH $(BINDIR)/jobdone
  1021. X        @echo "\n\007Installation of programs and scripts complete\n"
  1022. X
  1023. make_doc:
  1024. X        (cd ../man; \
  1025. X        $(SHELL) ./lman *.l)
  1026. X        @echo "\n\007Readable man pages conversion complete\n"
  1027. X
  1028. inst_man:
  1029. X        (cd ..; \
  1030. X        cp man/*.l $(MANDIR))
  1031. X        @echo "\n\007Installation of man pages complete\n"
  1032. X
  1033. X$(BINDIR)/rc.QBATCH:    rc.QBATCH
  1034. X        cp rc.QBATCH $(BINDIR);
  1035. X
  1036. X$(BINDIR)/jobdone:    jobdone
  1037. X        cp jobdone $(BINDIR);
  1038. X
  1039. X$(BINDIR)/jj:    jj
  1040. X        cp $? $(BINDIR)
  1041. X
  1042. X$(BINDIR)/jk:    jk
  1043. X        cp $? $(BINDIR)
  1044. X
  1045. X$(BINDIR)/jm:    jm
  1046. X        cp $? $(BINDIR)
  1047. X
  1048. X$(BINDIR)/jn:    jn
  1049. X        cp $? $(BINDIR)
  1050. X
  1051. X$(BINDIR)/jr:    jr
  1052. X        cp $? $(BINDIR)
  1053. X
  1054. X$(BINDIR)/js:    js
  1055. X        cp $? $(BINDIR)
  1056. X
  1057. X$(BINDIR)/qa:    qa
  1058. X        cp $? $(BINDIR)
  1059. X
  1060. X$(BINDIR)/qc:    qc
  1061. X        cp $? $(BINDIR)
  1062. X
  1063. X$(BINDIR)/qd:    qd
  1064. X        cp $? $(BINDIR)
  1065. X
  1066. X$(BINDIR)/qe:    qe
  1067. X        cp $? $(BINDIR)
  1068. X
  1069. X$(BINDIR)/qf:    qf
  1070. X        cp $? $(BINDIR)
  1071. X
  1072. X$(BINDIR)/qg:    qg
  1073. X        cp $? $(BINDIR)
  1074. X
  1075. X$(BINDIR)/qh:    qh
  1076. X        cp $? $(BINDIR)
  1077. X
  1078. X$(BINDIR)/ql:    ql
  1079. X        cp $? $(BINDIR)
  1080. X
  1081. X$(BINDIR)/qp:    qp
  1082. X        cp $? $(BINDIR)
  1083. X
  1084. X$(BINDIR)/qs:    qs
  1085. X        cp $? $(BINDIR)
  1086. X
  1087. X$(BINDIR)/qw:    qw
  1088. X        cp $? $(BINDIR)
  1089. X
  1090. shar:        
  1091. X        (cd ..; \
  1092. X        rm -f qbatch.[0-9][0-9]; \
  1093. X        makekit -nqbatch. -m)
  1094. X
  1095. clean:
  1096. X        rm -f *.o core $(PROGS)
  1097. END_OF_FILE
  1098. if test 4658 -ne `wc -c <'src/Makefile'`; then
  1099.     echo shar: \"'src/Makefile'\" unpacked with wrong size!
  1100. fi
  1101. # end of 'src/Makefile'
  1102. fi
  1103. if test -f 'src/qc.c' -a "${1}" != "-c" ; then 
  1104.   echo shar: Will not clobber existing file \"'src/qc.c'\"
  1105. else
  1106. echo shar: Extracting \"'src/qc.c'\" \(4984 characters\)
  1107. sed "s/^X//" >'src/qc.c' <<'END_OF_FILE'
  1108. X/************************************************************************/
  1109. X/*                                     */
  1110. X/* qc .. queue create. create a batch processing queue with an optional */
  1111. X/*       processing priority, spooling area, monitor, or fixed context    */
  1112. X/*       status.                                    */
  1113. X/*                                                  */
  1114. X/* 0r    change the priority, spooling area, monitor or fixed context    */
  1115. X/*       status of a queue.                        */
  1116. X/*                                     */
  1117. X/*    usage: qc [ -m <monitor>] [-p<priority>] [-s<spoolpath>] qname  */
  1118. X/*                                     */
  1119. X/*   Copyright (c) Vita Services 1990                                   */
  1120. X/*             (c) Vita Fibres   1990 1991                              */
  1121. X/*                                     */
  1122. X/************************************************************************/
  1123. X
  1124. X#include <stdlib.h>
  1125. X#include "qbatch.h"
  1126. int mflag, sflag = 0, pflag = 0, pval = 0, fixedcontext = 0;
  1127. char *queuename;
  1128. char queue [64];
  1129. char qpath [64];
  1130. char monitor[64];
  1131. struct stat status;
  1132. int fpq;
  1133. XFILE *fp;
  1134. main (argc, argv)
  1135. int argc;
  1136. char * argv[];
  1137. X{
  1138. X    int c;
  1139. X    extern char *optarg;
  1140. X    extern int   optind;
  1141. X    if (getuid() != 0)
  1142. X    {
  1143. X        fprintf (stderr, "Must be root to create a queue\n");
  1144. X        qb_term (-1);
  1145. X    }
  1146. X    while ((c = getopt (argc, argv, "fm:p:s:v")) != -1)
  1147. X    switch (c)
  1148. X    {
  1149. X        case 's':
  1150. X            strcpy (qpath, optarg);
  1151. X            sflag ++;
  1152. X            break;
  1153. X        case 'p':
  1154. X            pval = atoi (optarg);
  1155. X        pflag ++;
  1156. X            break;
  1157. X        case 'f':
  1158. X            fixedcontext ++; 
  1159. X            break;
  1160. X        case 'm':
  1161. X            strcpy (monitor, optarg);
  1162. X        mflag ++;
  1163. X            break;
  1164. X        case 'v':   q_version();
  1165. X    case '?': qb_term (-1);
  1166. X    }
  1167. X    if (optind >= argc)
  1168. X    {
  1169. X        fprintf (stderr, "Invalid or missing queue name!\n");
  1170. X        qb_term (-1);
  1171. X    }
  1172. X    queuename = argv[optind];
  1173. X    if (sflag) 
  1174. X    {
  1175. X    if (*qpath != '/')
  1176. X    {
  1177. X        fprintf (stderr, "Relative pathspecs not permitted\n");
  1178. X        qb_exit (-1);
  1179. X    }
  1180. X        if (strlen (qpath) > 63)
  1181. X        {
  1182. X            fprintf (stderr, "Queue directory path length > 63 bytes\n");
  1183. X            qb_term (-1);
  1184. X        }
  1185. X    }
  1186. X    else strcpy (qpath, SPOOLPATH);
  1187. X    if ((monitor[0] != 0) && (strcmp (monitor, "NONE")) != 0)
  1188. X    {
  1189. X        if (strlen (monitor) > 63)
  1190. X        {
  1191. X            fprintf (stderr, "Monitor path length > 63 bytes\n");
  1192. X            qb_term (-1);
  1193. X        }
  1194. X    if (*monitor != '/')
  1195. X    {
  1196. X        fprintf (stderr, "Relative pathspecs not permitted\n");
  1197. X        qb_exit (-1);
  1198. X    }
  1199. X        if (access(monitor, W_OK) == 0) /* monitor path is accessible */
  1200. X        {
  1201. X            fp = fopen (monitor, "w");
  1202. X            if (fp == NULL) /* monitor is a directory */
  1203. X            {
  1204. X        if (monitor [strlen(monitor) - 1] != '/')
  1205. X                strcat (monitor, "/");
  1206. X                strcat (monitor, queuename);
  1207. X                strcat (monitor, ".mon");
  1208. X            }
  1209. X            else fclose (fp);
  1210. X        }
  1211. X        else            /* file does not exist or we don't have access */
  1212. X        {
  1213. X            fp = fopen (monitor, "w"); /*can we create it? */
  1214. X            if (fp == NULL)
  1215. X            {
  1216. X                fprintf (stderr, "Invalid path for monitor: %s\n", monitor);
  1217. X                qb_term (-1);
  1218. X            }
  1219. X            else 
  1220. X            {
  1221. X                fclose (fp);
  1222. X                unlink (monitor);
  1223. X            }
  1224. X        }
  1225. X    }
  1226. X    else 
  1227. X    {
  1228. X    if (strcmp (monitor, "NONE") != 0)
  1229. X    {
  1230. X        strcpy (monitor, qpath);
  1231. X        if (monitor[strlen(monitor) -1] != '/') strcat (monitor, "/");
  1232. X        strcat (monitor, queuename);
  1233. X        strcat (monitor, ".mon");
  1234. X    }
  1235. X    }
  1236. X    strcpy     (queue, QUEUEPATH);
  1237. X    strcat     (queue, queuename);
  1238. X    qb_setterm();
  1239. X    if (access(queue, F_OK))
  1240. X    {
  1241. X    strcpy (head.q_magic, "qBq");
  1242. X        head.qh_pid       = 0;
  1243. X        head.qh_noentries = 0;
  1244. X        head.qh_hiwater   = 0;
  1245. X    head.qh_priority  = 0;
  1246. X        head.qh_flags     = (unsigned int) qh_enabled;
  1247. X        head.qh_proc      = 0;
  1248. X        head.qh_start     = 0;
  1249. X        head.qh_queued      = 0;
  1250. X        head.qh_real      = 0;
  1251. X        head.qh_user      = 0;
  1252. X        head.qh_system    = 0;
  1253. X        head.qh_jobcount  = 0;
  1254. X    sflag = mflag = 1;
  1255. X        fpq = open (queue, O_RDWR+O_CREAT, 0644);
  1256. X        if (fpq == -1)
  1257. X        {
  1258. X            fprintf (stderr, "cannot create queue\n");
  1259. X            qb_term (-1);
  1260. X        }
  1261. X        q_lock(fpq);
  1262. X    }
  1263. X    else 
  1264. X    {
  1265. X        fpq = open (queue, O_RDWR);
  1266. X        if (fpq == -1)
  1267. X        {
  1268. X            fprintf (stderr, "cannot open queue\n");
  1269. X            qb_term (-1);
  1270. X        }
  1271. X        q_lock(fpq);
  1272. X        lseek (fpq, 0, SEEK_SET);
  1273. X        read (fpq, &head, sizeof(head));
  1274. X    if (bad_queue()) qb_exit(-1);
  1275. X    }
  1276. X    if (sflag) strcpy (head.qh_spool, qpath);
  1277. X    if (mflag) strcpy (head.qh_defmon, monitor);
  1278. X    if (pflag) head.qh_priority  = pval;
  1279. X    if (fixedcontext)
  1280. X    {
  1281. X    if ((head.qh_flags & qh_fixed) == 0)
  1282. X         head.qh_flags += (unsigned int) qh_fixed;
  1283. X    else    head.qh_flags -= (unsigned int) qh_fixed;
  1284. X    }
  1285. X    lseek (fpq, 0, SEEK_SET);
  1286. X    write (fpq, &head, sizeof(head));
  1287. X    qb_term (0);
  1288. X}
  1289. END_OF_FILE
  1290. if test 4984 -ne `wc -c <'src/qc.c'`; then
  1291.     echo shar: \"'src/qc.c'\" unpacked with wrong size!
  1292. fi
  1293. # end of 'src/qc.c'
  1294. fi
  1295. if test -f 'src/ql.c' -a "${1}" != "-c" ; then 
  1296.   echo shar: Will not clobber existing file \"'src/ql.c'\"
  1297. else
  1298. echo shar: Extracting \"'src/ql.c'\" \(4918 characters\)
  1299. sed "s/^X//" >'src/ql.c' <<'END_OF_FILE'
  1300. X/************************************************************************/  
  1301. X/*                                                                      */
  1302. X/* ql .. queue list .. list the contents of a queue                     */
  1303. X/*                                                                      */
  1304. X/*      usage: ql [-a]  qname                                           */
  1305. X/*                                                                      */
  1306. X/*   Copyright (c) Vita Services 1990                                   */
  1307. X/*             (c) Vita Fibres   1990 1991                              */
  1308. X/*                                                                      */
  1309. X/************************************************************************/
  1310. X
  1311. X#include "qbatch.h"
  1312. X#include <time.h>
  1313. XFILE *fpq;
  1314. char buff[128];
  1315. char started[7], repeated[3], killed[3], enabled[3], stopped[3], halted[3];
  1316. char Yes[] = "Yes";
  1317. char No[]  = "No"; 
  1318. struct tm *jtimes;
  1319. char *queuename;
  1320. int i, aflag;
  1321. void q_version()
  1322. X{
  1323. X    puts (&QbSID[5]);
  1324. X    puts ("");
  1325. X    puts (&QbCR1[5]);
  1326. X    puts (&QbCR2[5]);
  1327. X    puts ("");
  1328. X    exit(0);
  1329. X}
  1330. int bad_queue()
  1331. X{
  1332. X    if (strcmp (head.q_magic, "qBq") != 0)
  1333. X    {
  1334. X        fprintf(stderr,"%s is not a valid QBATCH queue\007\n", queuename);
  1335. X        return(-1);
  1336. X    }
  1337. X    return(0);
  1338. X}
  1339. main (argc,argv)
  1340. int argc;
  1341. char *argv[];
  1342. X{
  1343. X    int c;
  1344. X    extern char *optarg;
  1345. X    extern int optind;
  1346. X    if (argc == 1)
  1347. X    {
  1348. X        puts ("Usage ql [-a] <qname>");
  1349. X        exit (0);
  1350. X    }
  1351. X    while ((c = getopt (argc, argv, "av")) != -1)                       
  1352. X    switch (c)
  1353. X    {
  1354. X        case 'a':   aflag ++;
  1355. X                    break;
  1356. X        case 'v':   q_version();
  1357. X    case '?':   exit (-1);
  1358. X    }
  1359. X    if (optind >= argc)
  1360. X    {
  1361. X        fprintf (stderr, "Invalid or missing queue name!\n");
  1362. X        exit (-1);
  1363. X    }
  1364. X    queuename = argv[optind];
  1365. X    strcpy (buff, QUEUEPATH);
  1366. X    strcat (buff, queuename);
  1367. X    fpq = fopen (buff, "r");
  1368. X    if (fpq == NULL)
  1369. X    {
  1370. X        fprintf (stderr, "Invalid queue name: %s!\n",queuename);
  1371. X        exit (-1);
  1372. X    }
  1373. X    fread (&head, sizeof(head), 1, fpq);
  1374. X    if (bad_queue())
  1375. X    {
  1376. X    fclose (fpq);
  1377. X    exit(-1);
  1378. X    }
  1379. X    if (head.qh_pid) sprintf (started, "%d", head.qh_pid);
  1380. X    else strcpy (started, " No");
  1381. X    printf ("Status of           : %s %s\n", queuename,
  1382. X    (head.qh_flags&qh_fixed) ? "(fixed context)":"");
  1383. X    printf ("Spooling in         : %s\n", head.qh_spool);
  1384. X    printf ("Monitor is          : %s\n", head.qh_defmon);
  1385. X    printf ("Priority is         : %d\n", head.qh_priority);
  1386. X    if (head.qh_proc != 0)
  1387. X    {
  1388. X        jtimes = localtime(&head.qh_proc);
  1389. X        printf ("Queue last started  : %2d/%02d/%02d %2d:%02d:%02d\n",
  1390. X            jtimes->tm_mday, jtimes->tm_mon+1, jtimes->tm_year,
  1391. X            jtimes->tm_hour, jtimes->tm_min, jtimes->tm_sec); 
  1392. X    }
  1393. X    else printf ("Queue not running\n");
  1394. X    if (head.qh_start != 0)
  1395. X    {
  1396. X        jtimes = localtime(&head.qh_start);
  1397. X        printf ("Current job started : %2d/%02d/%02d %2d:%02d:%02d\n",
  1398. X            jtimes->tm_mday, jtimes->tm_mon+1, jtimes->tm_year,
  1399. X            jtimes->tm_hour, jtimes->tm_min, jtimes->tm_sec); 
  1400. X    }
  1401. X    else printf ("Queue is idle\n");
  1402. X    printf ("\n   No of    Active   Queue      Job       Job      Queue     Queue\n");
  1403. X    printf   ("  Entries   (pid)  Accepting Repeated    Killed    Halted   Stopped\n");
  1404. X    printf ("   %5d",head.qh_noentries);
  1405. X    printf ("    %-5s", started);
  1406. X    if (head.qh_flags&qh_enabled) printf ("     Yes");
  1407. X    else                          printf ("     No ");
  1408. X    if (head.qh_flags&qh_repeat)  printf ("       Yes");
  1409. X    else                          printf ("       No ");
  1410. X    if (head.qh_flags&qh_kill)    printf ("       Yes");
  1411. X    else                          printf ("       No ");
  1412. X    if (head.qh_flags&qh_halt)    printf ("       Yes");
  1413. X    else                          printf ("       No ");
  1414. X    if (head.qh_flags&qh_stop)    printf ("       Yes\n\n");
  1415. X    else                          printf ("       No\n\n");
  1416. X    for (i = 0; i< head.qh_noentries;i++)
  1417. X    {
  1418. X        fread (&entry, sizeof(entry), 1, fpq);
  1419. X        printf ("%3d  ", entry.qe_jobno);
  1420. X        if   (entry.qe_status) printf ("%5d ",entry.qe_status);
  1421. X        else                   printf ("      ");
  1422. X        printf ("%-10s  ", entry.qe_uname);
  1423. X        printf ("%-8s  ", entry.qe_tty);
  1424. X        jtimes = localtime(&entry.qe_submitted);
  1425. X        printf ("%2d/%02d/%02d %2d:%02d:%02d  ",
  1426. X            jtimes->tm_mday, jtimes->tm_mon+1, jtimes->tm_year,
  1427. X            jtimes->tm_hour, jtimes->tm_min, jtimes->tm_sec); 
  1428. X        printf ("%s\n", entry.qe_jobname);
  1429. X        if (aflag)
  1430. X        {
  1431. X            printf ("uid: %d, gid: %d, jcl: %s\n",entry.qe_uid, entry.qe_gid, entry.qe_jcl);
  1432. X            if (entry.qe_monitor[0] == 0)  printf ("Monitor : default\n\n");
  1433. X            else                           printf ("Monitor : %s\n\n", entry.qe_monitor);
  1434. X        }
  1435. X    }
  1436. X    printf ("\n");
  1437. X    fclose (fpq);
  1438. X    exit (0);
  1439. X}
  1440. END_OF_FILE
  1441. if test 4918 -ne `wc -c <'src/ql.c'`; then
  1442.     echo shar: \"'src/ql.c'\" unpacked with wrong size!
  1443. fi
  1444. # end of 'src/ql.c'
  1445. fi
  1446. echo shar: End of archive 3 \(of 6\).
  1447. cp /dev/null ark3isdone
  1448. MISSING=""
  1449. for I in 1 2 3 4 5 6 ; do
  1450.     if test ! -f ark${I}isdone ; then
  1451.     MISSING="${MISSING} ${I}"
  1452.     fi
  1453. done
  1454. if test "${MISSING}" = "" ; then
  1455.     echo You have unpacked all 6 archives.
  1456.     rm -f ark[1-9]isdone
  1457. else
  1458.     echo You still need to unpack the following archives:
  1459.     echo "        " ${MISSING}
  1460. fi
  1461. ##  End of shell archive.
  1462. exit 0
  1463.  
  1464. exit 0 # Just in case...
  1465. -- 
  1466. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1467. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1468. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1469. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1470.